home *** CD-ROM | disk | FTP | other *** search
- ░
- ░ ░ ░ ▄▓
- ▄▄ ░░ ▄▄▄▄■ ░░▀ ■▄▄▄ ▄▄ ▐█▓▌
- ▄▀▀ ▀■ ▀ ░░ ▀ ■▀ ▀▀▄ ██▌
- ■ ▄▄▀▀ ▄▄██▀██▄▄ ▄▄▄███▄▄ ▀▄▄ ■ ▄▄▄███▄▄▐██ ▄▄████▄▄
- ▀▄▄ ▄▀▀ ▄███▀ ▀██▓▄ ▄████▀ ▀██▓▄ ▀▄ ▄▄▀ ▄████▀ ▀██▓██ ▄████▀ ▀██▓▄
- ▀▀ ▄ ▐███▌ ░ ▐██▓▌ ▐████▌ ░ ▐██▓▌ ▄ ▀▀ ▐████▌ ░ ▐████▌ ▐████▌ ▐██▓▌
- ■██▄▄▓▌ ████ ░▒░ ████ █████▄▄▄ ▀▀▀▀ ▐█▄▄█▓ █████ ░ █████ █████▄▄▀▀▀▀▀▀▀
- ▐████ ░░ ▓██▌ ░▒▓▒░ ▐███ ▄▄▄▄▄ ▀▀▀████▄ ████▌ ▓███▌ ▐████ ▓███▌ ░░░░░░
- ░ ███▌ ░ ▐▓███ ░▒▓▒░ ▓███▌▓███▌ ░░░ ▐████ ▐▓██ ▓███▌ ▄▀▀ ▐████ ▓███▌ ░░░░░░░
- ▓██▌ ▐▓███ ░▒░ ▓███▌▐▓███ ░ ▓███▌ ▐▓██ ▐▓███ ▓███▌ ▐▓███
- ▐▓███ ▐▓▓██▌ ░ ▐▓███▌ ▓▓██▌ ▐▓███ ▓███▌ ▓▓██▌ ░ ▐▓███ ▓▓██▌
- ▓▓▓██▌ ■▓▓▓▓██ ░ ▓█████■ ▀▓▓█▄ ▄▓██▀ ▐▓████ ▄ ▀▓██▄ ▄▓██▀ ▀▓██▄
- ▀▓███▄ ▀▀▀██▄ ▄▓█▀▀▀ ▀▀█▀▀ ▄▓▓▓▀▀ ▀▀█▀▀ ▀▀▀▀ js
- ▀▀▀▀▀▄▄ ░ iNSiDE ▄▄▀▀▀▀▀
- ░ ▀▄ ░ ░░ ▄▀
- ░░ ░ ░░
-
- Tutor : _duelist
- Data Wrote : July 20, 1999
- Who : Medium skilled crackers
- Target : Lazarus' Unreversable Algo - Part I
- Size : 343kb
- Tools Used : SoftIce, Tasm (or any asm compiler), W32dasm (not strictly needed)
-
-
- - INTRODUCTION: -
-
- Hi. Well it seems what we've got here it's a tuturial to reverse an unreversable
- algo, which seems a little contradiction. But no, we won't exactly reverse it in
- the true value of the word, coz as you'll later see this algo is actually not
- 'reversable'. What we are going to do, it's *use* it to crack itself... Go on and
- read the rest of the deal, i hope you enjoy this...
-
-
- - CRACKING STEPS: -
-
- Start up the crackme, enter any dummy code you like (must be a valid integer) then
- bpx hmemcpy. Now add/del any number from the code you entered to make the app check
- if it is a valid code. Ignore first break (press F5) since that is the char being
- drawn/erased by windows, but on second break, press F12 until you are into the code
- ifself:
-
- :004015CF 8D45FC lea eax, dword ptr [ebp-04]
- :004015D2 E8D95C0400 call 004472B0 ; gets length of code
- :004015D7 83F80A cmp eax, 0000000A ; matches against 10
- :004015DA 8D45FC lea eax, dword ptr [ebp-04] ; and stores result in dl
- :004015DD 0F94C2 sete dl ; <--/
- :004015E0 83E201 and edx, 00000001
- :004015E3 52 push edx ; push it onto stack
- :004015E4 BA02000000 mov edx, 00000002
- :004015E9 FF4DDC dec [ebp-24]
- :004015EC E87B5C0400 call 0044726C
- :004015F1 59 pop ecx ; pop it down, this is dl value
- :004015F2 84C9 test cl, cl
- :004015F4 0F842A020000 je 00401824 ; if length != Ah then screwed
- :004015FA 33C0 xor eax, eax
- :004015FC 8945B4 mov dword ptr [ebp-4C], eax
- :004015FF 33D2 xor edx, edx
- :00401601 8955B0 mov dword ptr [ebp-50], edx
- :00401604 EB46 jmp 0040164C
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00401692(C)
- |
- :00401606 66C745D02000 mov [ebp-30], 0020
- :0040160C 8D45F4 lea eax, dword ptr [ebp-0C]
- :0040160F E820020000 call 00401834
- :00401614 8BD0 mov edx, eax
- :00401616 FF45DC inc [ebp-24]
- :00401619 8B4DBC mov ecx, dword ptr [ebp-44]
- :0040161C 8B81C4020000 mov eax, dword ptr [ecx+000002C4]
- :00401622 E8F5050200 call 00421C1C
- :00401627 8D45F4 lea eax, dword ptr [ebp-0C]
- :0040162A 8B55B0 mov edx, dword ptr [ebp-50]
- :0040162D 42 inc edx
- :0040162E E831020000 call 00401864
- :00401633 0FBE08 movsx ecx, byte ptr [eax] ; gets each letter from name
- :00401636 014DB4 add dword ptr [ebp-4C], ecx ; adds it to ebp-4c
- :00401639 FF4DDC dec [ebp-24]
- :0040163C 8D45F4 lea eax, dword ptr [ebp-0C]
- :0040163F BA02000000 mov edx, 00000002
- :00401644 E8235C0400 call 0044726C
- :00401649 FF45B0 inc [ebp-50]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00401604(U)
- |
- ......... xxxxxx NOT IMPORTANT CODE
-
- :0040168F 59 pop ecx
- :00401690 85C9 test ecx, ecx
- :00401692 0F856EFFFFFF jne 00401606
- :00401698 817DB40D020000 cmp dword ptr [ebp-4C], 0000020D ; *real* checking starts here
- :0040169F 0F857F010000 jne 00401824 ; laz did a mistake here, read below
- :004016A5 66C745D02C00 mov [ebp-30], 002C
- :004016AB 8D45F0 lea eax, dword ptr [ebp-10]
- :004016AE E881010000 call 00401834
- :004016B3 8BD0 mov edx, eax
- :004016B5 FF45DC inc [ebp-24]
- :004016B8 8B4DBC mov ecx, dword ptr [ebp-44]
- :004016BB 8B81C4020000 mov eax, dword ptr [ecx+000002C4]
- :004016C1 E856050200 call 00421C1C
- :004016C6 8D45F0 lea eax, dword ptr [ebp-10]
- :004016C9 8B00 mov eax, dword ptr [eax]
- :004016CB E81C4F0300 call 004365EC
- :004016D0 8945AC mov dword ptr [ebp-54], eax
- :004016D3 FF4DDC dec [ebp-24]
- :004016D6 8D45F0 lea eax, dword ptr [ebp-10]
- :004016D9 BA02000000 mov edx, 00000002
- :004016DE E8895B0400 call 0044726C
- :004016E3 8B4DAC mov ecx, dword ptr [ebp-54] ; our serial, in dec format
- :004016E6 33C0 xor eax, eax
- :004016E8 894DA4 mov dword ptr [ebp-5C], ecx
- :004016EB 8945A8 mov dword ptr [ebp-58], eax
- :004016EE DF6DA4 fild qword ptr [ebp-5C] ; load our serial into the fpu
- :004016F1 83C4F8 add esp, FFFFFFF8
- :004016F4 DD1C24 fstp qword ptr [esp]
- :004016F7 E874040400 call 00441B70 ; gets square root of our serial
- :004016FC 83C408 add esp, 00000008
- :004016FF E84CF10300 call 00440850 ; rounds it and moves into eax
- :00401704 8945AC mov dword ptr [ebp-54], eax ; which is moved into ebp-54
- :00401707 66C745D03800 mov [ebp-30], 0038
- :0040170D 8D45EC lea eax, dword ptr [ebp-14]
- :00401710 E81F010000 call 00401834
- :00401715 8BD0 mov edx, eax
- :00401717 FF45DC inc [ebp-24]
- :0040171A 8B4DBC mov ecx, dword ptr [ebp-44]
- :0040171D 8B81C4020000 mov eax, dword ptr [ecx+000002C4]
- :00401723 E8F4040200 call 00421C1C
- :00401728 8D45EC lea eax, dword ptr [ebp-14]
- :0040172B 8B00 mov eax, dword ptr [eax]
- :0040172D E8BA4E0300 call 004365EC
- :00401732 52 push edx
- :00401733 50 push eax
- :00401734 8B45AC mov eax, dword ptr [ebp-54] ; not important, value never used
- :00401737 F76DAC imul [ebp-54] ; " " "
- :0040173A 33D2 xor edx, edx
- :0040173C 3B542404 cmp edx, dword ptr [esp+04]
- :00401740 7503 jne 00401745
- :00401742 3B0424 cmp eax, dword ptr [esp] ; this is actually a dummy check
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00401740(C)
- |
- :00401745 0F94C1 sete cl
- :00401748 83C408 add esp, 00000008
- :0040174B 83E101 and ecx, 00000001
- :0040174E 8D45EC lea eax, dword ptr [ebp-14]
- :00401751 BA02000000 mov edx, 00000002
- :00401756 51 push ecx
- :00401757 FF4DDC dec [ebp-24]
- :0040175A E80D5B0400 call 0044726C
- :0040175F 59 pop ecx
- :00401760 84C9 test cl, cl
- :00401762 B902000000 mov ecx, 00000002
- :00401767 8B45AC mov eax, dword ptr [ebp-54] ; square of serial into eax
- :0040176A 33D2 xor edx, edx
- :0040176C F7F1 div ecx ; div it by ecx (2)
- :0040176E 8945AC mov dword ptr [ebp-54], eax
- :00401771 834DAC7B or dword ptr [ebp-54], 0000007B ; or result from div with 7Bh
- :00401775 8B45AC mov eax, dword ptr [ebp-54]
- :00401778 C1E005 shl eax, 05 ; shl it by 5
- :0040177B 8D0480 lea eax, dword ptr [eax+4*eax] /
- :0040177E 8D0480 lea eax, dword ptr [eax+4*eax] | multiplie value by 5
- :00401781 8D0480 lea eax, dword ptr [eax+4*eax] | for five times, one
- :00401784 8D0480 lea eax, dword ptr [eax+4*eax] | for each code line (doh)
- :00401787 8D0480 lea eax, dword ptr [eax+4*eax] \
- :0040178A 8945AC mov dword ptr [ebp-54], eax
- :0040178D 8145ACA4F52203 add dword ptr [ebp-54], 0322F5A4 ; add 0322F5A4h to it
-
- ......... xxxxxx NOT IMPORTANT CODE
-
- :004017CC 3B0424 cmp eax, dword ptr [esp] ; does the serial equal
- ; (((((shl((sqrt(serial) or 7Bh),5)/2)*5)*5)*5)*5)*5)+0322F5A4h
-
-
- - NOW WHAT: -
-
- Ok, now we know that if:
-
- sum up off ascii values for serial's chars matches 20Dh
-
- AND
-
- serial == (((((shl((sqrt(serial) or 7Bh),5)/2)*5)*5)*5)*5)*5)+0322F5A4h
-
-
- We've got a winner :) and we'll get the "You did it" message.
- So, since the value calculated from the square root of the serial is not
- compared to any constant but to the serial itself, the algo is really not
- reversable. We can, however, code a little bruteforcer that will give you
- the valid serial(s). You can rip the code from win32dasm, but i recommend
- you *some* optimization since every second is important there. Attached is
- my commented bruteforcer, i suggest you have a look at it...
- By the way the number of patterns checked is 4.294.967.295 if u let it run
- from the beggining to the end (all possible patterns) and the first valid
- code i found was 2624922756, and the only one.
-
- About lazarus' mistake, he did check if the sum of the ascii values for
- the serial's chars matched 20D, that spares the bruteforcer a *lot* of time
- cause if it doesn't match, bruteforcer passes immediatly to another code.
- Remember to always make up ways to reduce bruteforcing time whenever you
- use this kind of aproach, BUT it should be used only when no other methods
- can be employed since it is kinda lame when used in another situations.
-
-
- - GREETINGS: -
-
- E_Bliss, tC, MisterE, CodeZero, R!SC (great cracker), Lazarus, elmopio,
- Acid_Burn, _pain (u leeto :P), Carpathia, DEZM, Neural_N, fresh, noos,
- Bjanes, etc etc... argh so many people to greet... #c4n masses! :)
-